﻿using System;
using System.IO;
using System.Text.RegularExpressions;
using NUnit.Framework;
using SeleniumToolkit.Config;
using SeleniumToolkit.Util;

namespace SeleniumToolkit.Core
{
    public class SeleniumRemoteControlArgumentBuilderSpecs : SpecFor<SeleniumRemoteControlArgumentBuilder>
    {
        protected SeleniumConfiguration config;
        protected string arguments;
        protected string installDir;


        protected override void Context()
        {
            // write our registry setting so that we can tests "configurationless" mode
            // this hack assumes that the environment is 64bit
            //  AND
            // assumes that we have our libraries installed at this location
            RegistryKeyHelper helper = new RegistryKeyHelper(@"SOFTWARE\SeleniumToolkit", true);
            helper.SetValue("InstallDir", @"C:\Program Files (x86)\Selenium Toolkit");

            config = new SeleniumConfiguration();
            installDir = config.RuntimeSettings.SeleniumRuntimePath;
        }

        public override SeleniumRemoteControlArgumentBuilder InitializeSubject()
        {
            return new SeleniumRemoteControlArgumentBuilder(config);
        }

        protected override void Because()
        {
            arguments = subject.GetArguments();
        }

        [TestFixture]
        public class WhenConstructingArguments : SeleniumRemoteControlArgumentBuilderSpecs
        {
            [Test]
            public void ShouldContainJar()
            {
                Regex regx = new Regex("-jar \".*\\\\selenium-server.jar\"");
                regx.IsMatch(arguments).ShouldBeTrue();
            }
        }

        [TestFixture]
        public class WhenFolderPathIsIncorrect : SeleniumRemoteControlArgumentBuilderSpecs
        {
            Exception ex;

            protected override void Context()
            {
                base.Context();
                config.RuntimeSettings.SeleniumRuntimePath = @"C:\Illegal-FilePath";
            }

            protected override void Because()
            {
                ex = new MethodThatThrows(base.Because).GetException();
            }

            [Test]
            public void ShouldThrowException()
            {
                ex.ShouldNotBeNull();
            }

            [Test]
            public void ShouldBeIOException()
            {
                ex.ShouldBeOfType(typeof(FileNotFoundException));
            }

            [Test]
            public void ShouldHaveSeleniumRcFilenameInMessage()
            {
                ex.Message.ShouldContain("selenium-server.jar");
            }
        }

        [TestFixture]
        public class WhenUsingAnonymousProxyServer : SeleniumRemoteControlArgumentBuilderSpecs
        {
            protected override void Context()
            {
                base.Context();
                config.RuntimeSettings.ProxyServer = "proxy.com";
                config.RuntimeSettings.ProxyPort = 8080;
            }

            [Test]
            public void ShouldHaveProxyServerInArguments()
            {
                arguments.ShouldContain("-Dhttp.proxyHost=proxy.com");
            }

            [Test]
            public void ShouldHaveProxyPortInArguments()
            {
                arguments.ShouldContain("-Dhttp.proxyPort=8080");
            }
        }

        [TestFixture]
        public class WhenUsingAuthenticatedProxyServer : SeleniumRemoteControlArgumentBuilderSpecs
        {
            protected override void Context()
            {
                base.Context();
                config.RuntimeSettings.ProxyServer = "proxy.com";
                config.RuntimeSettings.ProxyPort = 8080;
                config.RuntimeSettings.ProxyUser = "user1";
                config.RuntimeSettings.ProxyPassword = "password1";
            }

            [Test]
            public void ShouldHaveUserNameInArguments()
            {
                arguments.ShouldContain("-Dhttp.proxyUser=user1");
            }

            [Test]
            public void ShouldHavePasswordInArguments()
            {
                arguments.ShouldContain("-Dhttp.proxyPassword=password1");
            }
        }

        [TestFixture]
        public class WhenUsingUserExtensions : SeleniumRemoteControlArgumentBuilderSpecs
        {
            string tempFile = @"C:\temp.js";

            protected override void Context()
            {
                base.Context();

                File.WriteAllText(tempFile, "var i = null;");

                config.UserExtensions.Add(new UserExtensionElement("name", tempFile));
            }

            protected override void CleanUpContext_AfterAllSpecs()
            {
                if (File.Exists(tempFile))
                    File.Delete(tempFile);
            }

            [Test]
            public void ShouldHaveProperlyNamedJavascriptFile()
            {
                Regex regex = new Regex("-userExtensions \".*user-extensions.js\"");
                regex.IsMatch(arguments).ShouldBeTrue();
            }

            [Test]
            public void ShouldHaveUserExtensionsArgument()
            {
                arguments.Contains("-userExtensions").ShouldBeTrue();
            }
        }
    }

}
